Xin chào mừng bạn đã ghé thăm blog của Nguyễn Văn Tiến!.Chúc bạn sức khỏe, niềm vui và an lành!.
Hiển thị các bài đăng có nhãn Kinh nghiệm Lập trình. Hiển thị tất cả bài đăng
Hiển thị các bài đăng có nhãn Kinh nghiệm Lập trình. Hiển thị tất cả bài đăng

Thứ Năm, 18 tháng 8, 2016

Tổng quan mô hình MVC, So sánh mô hình MVC và mô hình 3 lớp

Model – View – Control

  1. Tổng quan:
Vào những năm 70 của thế kỷ 20, tại phòng thí nghiệm Xerox PARC ở Palo Alto. Sự ra đời của giao diện đồ họa (Graphical User Interface - GUI) và lập trình hướng đối tượng (Object Oriented Programming - OOP) cho phép lập trình viên làm việc với những thành phần đồ họa như những đối tượng đồ họa có thuộc tính và phương thức riêng của nó. Không dừng lại ở đó, những nhà nghiên cứu ở Xerox PARC còn đi xa hơn nữa khi họ cho ra đời cái gọi là kiến trúc MVC (viết tắt của Model – View – Controller).
Kiến trúc này ngày càng được phát triển và hoàn thiện nhằm giải quyết các vấn đề phát sinh cũng như các giải pháp cho quá trình phát triển phần mềm.

  1. Các thành phần trong MVC:
Trong kiến trúc này, hệ thống được chia thành 3 tầng tương ứng đúng với tên gọi của nó (Model – View – Controller). Ở đó nhiệm vụ cụ thể của các tầng được phân chia như sau:
 

  1. Model (Tầng dữ liệu): là một đối tượng hoặc một tập hợp các đối tượng biểu diễn cho phần dữ liệu của chương trình. Nó được giao nhiệm vụ cung cấp dữ liệu cho cơ sở dữ liệu và lưu dữ liệu vào các kho chứa dữ liệu. Tất cả các nghiệp vụ logic được thực thi ở Model. Dữ liệu vào từ người dùng sẽ thông qua View đến Controller và được kiểm tra ở Model trước khi lưu vào cơ sở dữ liệu. Việc truy xuất, xác nhận, và lưu dữ liệu là một phần của Model.
alt
Hình 1: Luồng xử lý của mô hình MVC
  1. View (Tầng giao diện): là phần giao diện với người dùng, bao gồm việc hiện dữ liệu ra màn hình, cung cấp các menu, nút bấm, hộp đối thoại, chọn lựa …, để người dùng có thể thêm, xóa. sửa, tìm kiếm và làm các thao tác khác đối với dữ liệu trong hệ thống.. Thông thường, các thông tin cần hiển thị được lấy từ thành phần Models.
  2. Controller (Tầng điều khiển): là phần điều khiển của ứng dụng, điều hướng các nhiệm vụ (task) đến đúng phương thức (method) có chức năng xử lý nhiệm vụ đó. Nó chịu trách nhiệm xử lý các tác động về mặt giao diện, các thao tác đối với models, và cuối cùng là chọn một view thích hợp để hiển thị ra màn hình.
  1. Ưu điểm & nhược điểm:
  1. Ưu điểm:
Phát triển phần mềm: Có tính chuyên nghiệp hóa, có thể chia cho nhiều nhóm được đào tạo nhiều kỹ năng khác nhau, từ thiết kế mỹ thuật cho đến lập trình đến tổ chức database. Giúp phát triển ứng dụng nhanh, đơn giản, dễ nâng cấp..
Bảo trì: Với các lớp được phân chia theo như đã nói, thì các thành phần của một hệ thống dễ được thay đổi, nhưng sự thay đổi có thể được cô lập trong từng lớp, hoặc chỉ ảnh hưởng đến lớp ngay gần kề của nó, chứ không phát tán náo loạn trong cả chương trình.
Mở rộng: Với các lớp được chia theo ba lớp như đã nói, việc thêm chức năng vào cho từng lớp sẽ dễ dàng hơn là phân chia theo cách khác.
  1. Nhược điểm:
Đối với dự án nhỏ việc áp dụng mô hình MC gây cồng kềnh, tốn thời gian trong quá trình phát triển. Tốn thời gian trung chuyển dữ liệu của các tầng
  1. So sánh mô hình MVC với mô hình 3 lớp:
Hình 2: So sánh mô hình MVC với mô hình 3 lớp
Hình 2: So sánh mô hình MVC với mô hình 3 lớp
  1. Điểm giống:
Tách rời programming core/business logic ra khỏi những phụ thuộc về tài nguyên và môi trường. Presentation Layer (PL) thể hiện giống như chức năng của View và Controller. Business Layer (BL) và Data Access Layer (DL) thể hiện giống như chức năng của Model. Như thế nhìn ở góc độ này, thì MVC tương đương với 3-layer (tất nhiên có chồng chéo như hình vẽ)
  1. Điểm khác:
Trong mô hình 3 lớp, quá trình đi theo chiều dọc, bắt đầu từ PL, sang BL, rồi tới DL, và từ DL, chạy ngược lại BL rồi quay ra lại PL.
Hình 3: Mô hình 3 lớp
Hình 3: Mô hình 3 lớp
Còn trong mô hình MCD, dữ liệu được nhận bởi View, View sẽ chuyển cho Controller cập nhật vào Model, rồi sau đó dữ liệu trong Model sẽ được đưa lại cho View mà không thông qua Controller, do vậy luồng xử lý này có hình tam giác.
alt
Hình 4: Mô hình MCD

Quản lý nguồn nhân lực dự án (Human Resource Management Plan)

Lập kế hoạch quản lý nguồn nhân lực dự án (Plan Human Resource Management )

  • Kế hoạch quản lý nguồn nhân lực dự án là quá trình xác định và tài liệu hóa các vai trò (project roles), trách nhiệm (responsibilities), kỹ năng cần thiết, mối quan hệ giữa các roles và tạo kế hoạch quản lý nhân viên trong một dự án. Lợi ích chính yếu của quá trình này là nó thiết lập được vai trò, trách nhiệm trong dự án cho mỗi cá nhân, sơ đồ tổ chức dự án, và kế hoạch quản lý nhân sự bao gồm việc khi nào thì cần người đổ vào dự án khi nào thì rút người ra. Các input đầu vào, kỹ thuật áp dụng và đầu ra của quá trình này các bạn có thể tham khảo hình bên dưới.
HumanResource_1.png
  • Việc lập kế hoạch quản lý nguồn nhân lực được sử dụng để xác định và nhận biết nguồn nhân lực cùng các kỹ năng cần thiết cho sự thành công của dự án. Ngoài những điểm đã đề cập ở trên như vai trò, trách nhiệm, thời gian load người vào dự án, thời gian release người khỏi dự án thì nó còn chỉ ra nhu cầu đào tạo, chiến lược xây dựng team, kế hoạch công nhận và khen thưởng nhân viên trong dự án, xem xét việc tuân thủ, vấn đề an toàn, và tác động của kế hoạch quản lý nhân sự đối với công ty, tổ chức.
  • Một bản kế hoạch quản lý nguồn nhân lực hiệu quả cần cân nhắc và plan cho sự sẵn có (availability) và sự cạnh tranh cho nguồn nhân lực hạn chế. Vai trò của dự án có thể assign cho cá nhân hoặc cho một Team. Các Team hoặc các team members có thể là nhân viên trong hoặc ngoài công ty. Thường trong một tổ chức chắc chắn sẽ có nhiều dự án khác chạy song song cùng project của bạn và việc cạnh tranh nguồn nhân lực, cạnh tranh về skill set của member. Với những yếu tố đó có thể ảnh hưởng tới chi phí, schedule, rủi ro và chất lượng của dự án. Đó là lý do tại sao một bản kế hoạch quản lý nhân lực hiệu quả cần phải cân nhắc và plan kỹ lưỡng cho tình huống đó.

Đầu vào (Inputs) của kế hoạch quản lý nguồn nhân lực

Như hình bên trên, inputs của việc lập kế hoạch quản lý nguồn nhân lực bao gồm 4 tài liệu
  • Project managemnet plan / Kế hoạch quản lý dự án
  • Activity resource plan / Yêu cầu resource để hoàn thành activity trong project
  • Enterprise environmental factors / Các yếu tố môi trường doanh nghiệp
  • Organizational process assets / Quy trình tài sản của tổ chức

1. Kế hoạch quản lý dự án

  • Kế hoạch quản lý dự án được sử dụng làm đầu vào để phát triển kế hoạch quản lý nguồn nhân lực. Những thông tin thường được sử dụng cho việc lập kế hoạch nhân lực bao gồm những yếu tố dưới đây, nhưng không hạn chế
    • Vòng đời của dự án (project life circle) và quy trình sẽ được áp dụng cho từng giai đoạn (phase) của dự án.
    • Công việc sẽ được làm như thế nào để hoàn thành mục tiêu của dự án
    • Kế hoạch quản trị thay đổi (Change management plan) thể hiện tài liệu thay đổi sẽ được quản lý, kiểm soát như thế nào.
    • Kế hoạch quản lý cấu hình (Configuration management plan) thể hiện việc quản lý cấu hình tài liệu làm như thế nào.
    • Nhu cầu và phương thức communication giữa các stakeholders
    • Đường cơ sở của dự án (Project baselines) được đảm bảo như thế nào.

2. Yêu cầu resource

  • Việc hoạch định nguồn nhân lực sử dụng yêu cầu resource để hoàn thành activity để xác định số nhân lực cần cho dự án. Những yêu cầu sơ bộ về các thành viên trong project team và các kỹ năng, năng lực của họ được xem xét tỉ mỉ là một phần quan trọng trong việc lập kế hoạch quản trị nguồn nhân lực.

3. Các yếu tố môi trường doanh nghiệp

  • Các yếu tố môi trường doanh nghiệp có thể ảnh hưởng tới kế hoạch quản trị nguồn nhân lực bao gồm
    • Văn hóa và cấu trúc doanh nghiệp
    • Nguồn nhân lực hiện có
    • Việc phân tán về mặt địa lý của các thành viên trong nhóm
    • Chính sách quản lý nhân sự
    • Điều kiện thị trường

4. Quy trình tài sản của tổ chức

  • Cũng như các yếu tố môi trường Quy trình, tài sản của tổ chức cũng là nhân tố ảnh hưởng tới kế hoạch quản trị nguồn nhân lực.
    • Quy trình tiêu chuẩn, chính sách và mô tả vai trò của tổ chức
    • Các template cho sơ đồ tổ chức và mô tả vị trí
    • Bài học kinh nghiệm (Lession learn) từ các project trước
    • Các thủ tục để xử lý vấn đề trong dự án và trong team

Công cụ và kỹ thuật (Tool & Techniques) trong lập kế hoạch

1. Sơ đồ tổ chức và Mô tả vị trí

  • Có rất nhiều dạng format để tài liệu hóa vai trò và trách nhiệm của team members. Hầu hết các định dạng rơi vào một trong ba loại sau: phân cấp (hierarchical), ma trận (matrix) và hướng văn bản (text-oriented).
HumanResource_2.png
  • Sơ đồ phân cấp: Đây là sơ đồ cấu trúc tổ chức truyền thống có thể được sử dụng để thể hiện vị trí và mối quan hệ trong dự án qua hình vẽ theo format từ trên xuống dưới. Trong khi WBS thể hiện những deliverables của dự án thì Cấu trúc phân cấp của tổ chức-OBS (Organizational Breakdown Structure) được sắp xếp theo phòng ban, đơn vi, team của tổ chức với các activity của project. Các stakeholders nhìn vào sơ đồ đó có thể hiểu được trách nhiệm của phòng ban trong dự án, mối quan hệ và cách thức communication giữa các bộ phận.
  • Sơ đồ ma trận: Sơ đồ ma trận phân công trách nhiệm (RAM - Responsibility assignment matrix) là một mạng lưới thể hiện nguồn lực của dự án được được assigned cho mỗi gói công việc. Nó được sử dụng để minh họa cho sự kết nối giữa các gói công việc hoặc các activity với mỗi thành viên trong dự án. Trong các dự án lớn thì RAM được phát triển theo nhiều level khác nhau. Ví dụ ở level cao thì gán trách nhiệm cho group nào, team nào phụ trách component hay package nào. Ở level thấp hơn thì RAM được sử dụng trong nhóm để định nghĩa vai trò, trách nhiệm và quyền hạn cho các activity cụ thể.
HumanResource_3.png
  • Format hướng văn bản: Trách nhiệm của team được yêu cầu mô tả chi tiết trong tài liệu theo format định sẵn. Thông thường ở các dạng phác thảo nhằm cung cấp các thông tin cơ bản như trách nhiệm, quyền hạn, năng lực, trình độ.

2. Networking

  • Networking là sự tương tác chính thức và không chính thức với những người khác trong một tổ chức, lĩnh vực hoặc môi trường chuyên biệt. Đó là cách để hiểu các yếu tố chính trị và cá nhân ảnh hưởng thế nào đến hiệu quả của các phương thức quản lý nhân sự khác nhau. Lợi ích của việc quản lý nguồn nhân lực có thể thấy từ sự thành công của Networking bằng cách nâng cao kiến thức và tiếp cận với các cơ hội nâng cao chuyên môn, và các cơ hội hợp tác bên ngoài. Nói lý thuyết phần này có thể bạn sẽ hơi khó hiểu, ví dụ nôm na của Networking là các cuộc gặp gỡ ăn trưa, ăn nhậu hay trò chuyện về các sự kiện, hội nghị chuyên đề ...

3. Lý thuyết của tổ chức

  • Lý thuyết của tổ chức cung cấp thông tin liên quan đến cách thức mà mọi người, teams, và đơn vị của tổ chức hành xử với nhau, với vấn đề nào đó (có thể hiểu đại khái là những kiến thức chung mà người trong cùng một tổ chức đều hiểu với nhau). Nếu những vấn đề chung được xác định trong Lý thuyết của tổ chức có thể giúp rút ngắn thời gian, chi phí, và effort cần thiết để lập kế hoạch quản lý nguồn nhân lực.

4. Phán xét chuyên môn

  • Khi xây dựng kế hoạch quản trị nguồn nhân lực thì phán xét chuyên môn được sử dụng để
    • Liệt kê yêu cầu sơ bộ cho các kỹ năng cần thiết
    • Đánh giá các role cần thiết cho dự án dựa trên mô tả role tiêu chuẩn trong tổ chức (ví dụ ở Framgia có mô tả Dev rank mấy phải có tiêu chuẩn gì, QA rank mấy ...)
    • Xác đinh sơ bộ số effort và số nhân sự để đạt được objectives của dự án
    • Cung cấp guideline về thời gian cần thiết để chuẩn bị nhân lực dựa trên bài học từ các dự án trước
    • Xác định rủi ro liên quan đến việc thu nhận, giữ và release nhân sự

5. Meetings

  • Khi lập kế hoạch quản lý nguồn nhân lực của dự án, đội ngũ quản lý dự án sẽ tổ chức các cuộc họp để lên kế hoạch. Những cuộc họp này sử dụng kết hợp các công cụ và kỹ thuật khác nhau để tất cả các thành viên trong nhóm quản lý dự án đạt được sự đồng thuận về kế hoạch quản lý nguồn nhân lực.

Output của kế hoạch quản lý nguồn nhân lực

  • Như trên hình process ở phần đầu thì output của quá trình này chính là Bản kế hoạch quản lý nguồn nhân lực (Human resource Management Plan ). Nó là một phần của kế hoạch quản lý dự án (Project Management Plan), cung cấp hướng dẫn về cách thức nguồn nhân lực của dự án cần được xác định, tuyển dụng, quản lý, và cuối cùng là release.
  • Một bản kế hoạch quản lý nguồn nhân lực sẽ bao gồm các mục sau, có thể có hoặc không tùy tổ chức
    • Vai trò và trách nhiệm
      • Vai trò của từng cá nhân: PM, BA, Comtor, BrSE, Dev, Tester ..
      • Quyền hạn truy cập vào resource của dự án, quyền ra quyết định, approve ...
      • Trách nhiệm được giao, các activity phải hoàn thành
      • Năng lực: skills và khả năng cần thiết
    • Sơ đồ tổ chức dự án
    • Kê hoạch quản lý nhân viên
      • Tiếp nhận nhân viên, khi nào thì nhận người vào dự án .. một số role khác nhau thì thời điểm join vào dự án cũng khác nhau nên cần phải có plan cho việc này
      • Resource calendar: lên lịch làm việc cho các members trong dự án dựa vào avaiability của resource
      • Training plan: một số dự án đòi hỏi phải training về nghiệp vụ, tools hoặc process thì cần plan cho việc ai học cái gì và thời gian như thế nào.
      • Ghi nhận và khen thưởng
      • Lên chiến lược cho việc tuân thủ rules, hợp đồng, chính sách ..
      • Bảo đảm an toàn cho nhân viên (khi tiếp xúc với thiết bị có thể gây hại)
      • Kế hoạch release: nhân lực chính là tiền vì vậy release lúc nào để đảm bảo tiến độ và tiết kiệm chi phí cần phải cân nhắc kỹ.

Thứ Hai, 15 tháng 8, 2016

Tech lead tốt - Tech lead tồi

Vào một ngày đẹp trời khi đang làm dự án mới, một kỹ sư người Nhật đã đáp cho tôi một đường dẫn đến bài viết "Good Tech Lead, Bad Tech Lead". Sau khi đọc xong, tôi cảm thấy đây là một bài viết hay và muốn được chia sẻ tới mọi người.
Để so sánh giữa sự "tốt" và "tồi" của một tech lead, chúng ta có thể xem các khía cạnh sau đây:

Làm việc nhóm

Tech lead tốt sẽ hành động như một thành viên, và coi mình thành công khi cả nhóm thành công. Anh ta sẽ lấy những việc khó khăn và dẹp những trở ngại để cho nhóm có thể hoạt động với công suất 100%. Anh ta làm việc để mở mang kiến thức cho cả nhóm, đảm bảo rằng kiến thức quan trọng của hệ thống không bị tập trung vào một hai cá nhân.
Tech lead tồi sẽ lấy những công việc có sự chú ý cao (high-profile) và nguồn cảm hứng duy nhất để anh ta làm đó là nhận được sự vẻ vang khi hoàn thành công việc đó.

Tầm nhìn kỹ thuật

Tech lead tốt có cái nhìn toàn diện cho hướng đi kỹ thuật của sản phẩm và đảm bảo rằng cả nhóm hiểu điều đó. Anh ta uỷ thác việc quyết định các tính năng sản phẩm cho thành viên khác. Anh ta nhận thấy sự thông minh của thành viên trong nhóm, tin tưởng họ và giao cho họ xử lý những mảng quan trọng của dự án.
Tech lead tồi tìm cách thoái thác việc giải thích và xác nhận về hướng đi kỹ thuật, thay vào đó là ra lệnh thực hiện những quyết định của bản thân. Anh ta giữ những kiến thức quan trọng cho riêng mình, điều này không đem lại hiệu quả trong công việc vì kiến thức không được chia sẻ rộng rãi dưới dạng các tài liệu.

Thảo luận và tranh luận

Tech lead tốt lắng nghe và khuyến khích tranh luận. Khi cả nhóm không thể giải quyết được một cuộc tranh luận, anh ta sẽ đưa ra một hình thức suy nghĩ mà có thể giúp nhóm giải quyết. Anh ta không tham gia thảo luận với một kết luận có trước mà luôn cho phép bản thân mình bị thuyết phục với những ý tưởng hay.
Tech lead tồi cho phép tranh luận kéo dài quá lâu mà không đi tới kết luận, làm cản trở năng suất của nhóm. Một số thì cắt ngang tranh luận quá sớm, kết thúc tranh luận bằng câu nói "mọi việc đã được quyết định từ trước". Đối với tech lead tồi thì việc thắng trong tranh luận quan trọng hơn là nhóm đi đến một quyết định đúng đắn.
pic
Hình minh hoạ: @blackmad

Quản lý dự án

Tech lead tốt là người chủ động. Anh ta đảm bảo tiến độ kỹ thuật. Anh ta làm việc cùng nhóm để ước lượng và xác định các milestone trung gian. Anh ta lường trước những rủi ro và đảm bảo rằng chúng được xem xét trước khi chúng trở thành một vấn đề. Anh ta xác định những rào cản kỹ thuật và giúp nhóm vượt qua những rào cản đó.
Tech lead tồi là người thụ động. Anh ta có thể giao phó công việc nhưng không theo dõi để đảm bảo tiến độ. Anh ta không đặt những milestone trung gian và hy vọng rằng mọi thứ sẽ kết nối lại với nhau vào phút cuối. Anh ta đợi đến trước khi tung sản phẩm mới thực hiện tests từ đầu tới cuối của hệ thống phức tạp. Anh ta cho phép thành viên lãng phí thời gian vào những điều thú vị nhưng không quan trọng.

Tính thực dụng

Tech lead tốt là người thực tế và đảm bảo sự cân bằng giữa việc làm tốt và việc hoàn thành. Anh ta chọn việc làm tắt khi nó tiện lợi chứ không phải vì lười nhác. Anh ta khuyến khích nhóm tìm ra các đường tắt tạm thời để giải quyết những vấn đề cản trở tiến độ chung, và xây dựng cơ sở hạ tầng ở mức thấp nhất có thể hoạt động được. Đối với một tech lead tốt thì chi tiết rất quan trọng. Chất lượng code, code review và kiểm thử quan trọng không kém việc hoàn thành đúng thời hạn.
Tech lead tồi đi đường tắt để tiết kiệm thời gian cho ngắn hạn nhưng tốn kém cho dài hạn, và để cho "món nợ kỹ thuật" tăng dần. Anh ta không thể phân biệt giữa những trường hợp nên theo sự tiện lợi và trường hợp nên theo sự hoàn hảo.

Liên lạc, giao tiếp

Tech lead tốt biết rằng vai trò của anh ấy quan trọng hơn là viết code, biết rằng giao tiếp hiệu quả là một phần thiết yếu của công việc, biết rằng thời gian dành cho việc làm nhóm hiệu quả hơn là thời gian không hoài phí. Anh ta nhận thức rằng chi phí cho việc liên lạc là cần thiết khi hoạt động nhóm, và anh ta hy sinh năng suất của bản thân mình cho năng suất chung của nhóm.
Tech lead tồi tin rằng anh ta là người năng suất nhất khi viết code, and nghĩ rằng giao tiếp, liên lạc là điều gây sao nhãng. Anh ta không tối ưu cho năng suất chung của nhóm, mà cho điều tốt nhất đối với anh ta. Anh ta trở nên cau có khi phải dành thời gian dẫn dắt nhóm.

Mối quan hệ với sản phẩm

Tech lead tốt sẽ có thảo luận với product manager và designer về vấn đề sản phẩm nên hoạt động ra sao. Anh ta không sợ việc phải chống lại những quyết định anh ta bất đồng, nhưng vẫn giữ ý nghĩ về mục tiêu của sản phẩm và biết khi nào nên dàn xếp để đạt được chúng. Anh ta phát hiện ra những lối đi vòng sáng tạo để cho những bó buộc về mặt kỹ thuật bị giảm đi, giúp cho project manager và designer hiểu được thử thách về kỹ thuật.
Tech lead tồi phó thác quyết định về sản phẩm cho người khác và không nhận sở hữu sản phẩm. Anh ta thoái thác vì những bó buộc kỹ thuật nhưng không đưa ra phương án khác hay lời giải thích.

Độ thích ứng

Tech lead tốt thích ứng tốt với sự thay đổi của yêu cầu sản phẩm và phản ứng điềm tĩnh trước những bất ngờ. Anh ta lường trước nơi mà thay đổi xảy ra và thiết kế code để xử lý chúng.
Tech lead tồi bực tức khi yêu cầu thay đổi và cho rằng sẽ không có gì thay đổi đâu khi thiết kế sản phẩm.

Tính cách

Tech lead tốt dễ tính nhưng quyết đoán. Tech lead tồi thường thích đối chất và hung hăng. Tech lead tốt hành xử tự nhiên và giành được sự kính trọng thông qua khả năng và công việc. Tech lead tồi nghĩ rằng danh hiệu nghiễm nhiên có được sự kính trọng và uy quyền. Tech lead tốt luôn tìm kiếm cách để cải thiện.
Tech lead tồi luôn trong trạng thái phòng thủ khi nhận được phản hồi. Tech lead tốt là người khiêm tốn và giúp nhóm nâng sự tự tin lên. Tech lead tồi là người kiêu ngạo và thấy vui vẻ khi làm cho thành viên có cảm giác "bề dưới".

Lời kết

Trong lúc làm việc, đôi khi ta không nhận ra mình là người tốt hay xấu, nhưng hy vọng khi đọc xong bài viết này các bạn có thể lùi lại một bước và đánh giá xem cách hành xử của mình với những đồng nghiệp cấp dưới đã giúp cho họ có một môi trường phát triển chưa?
Bài viết gốc ở đây

Thứ Ba, 7 tháng 6, 2016

Những nguyên tắc, định luật của lập trình mà chúng ta nên có sẵn trong đầu

Một vài định luật về lập trình hay nên share cho mọi người và cũng là textnote cho bản thân:

Nguyên tắc Demeter

Còn có tên gọi khác là nguyên tắc “càng biết ít càng tốt”.
Demeter là tên gọi của Nữ thần nông nghiệp, cũng là nữ thần phân phát trong thần thoại Hi Lạp. Tên bà được dùng để đánh dấu sự ra đời của nguyên tắc này, đây có thể xem là một triết lý nền tảng của việc lập trình được sinh ra từ một aspect-oriented programming (AOP) project cùng tên.
Quan điểm cơ bản của nguyên tắc này chính là : tối giản sự hiểu biết của 1 object về cấu trúc, thuộc tính của các object khác ngoài nó (bao gồm các thành phần con).
Nói một cách đơn giản là không được tiếp xúc với thuộc tính, method của các object khác một cách trực tiếp.
#Vi phạm nguyên tắc Demeter
console.log(aStudent.class.grade)

#Không vi phạm nguyên tắc Demeter
console.log(aStudent.getGrade())

Định luật Wirth

“Software gets slower faster than hardware gets faster” – “Tốc độ tiến hóa của phần cứng không bằng tốc độ thoái hóa của phần mềm.”
Có lẽ ý chính của nó là : lập trình ngày càng dùng nhiều tài nguyên phong phú nên framework phải luôn tiến hóa để phục vụ cho việc đó. Suy ra, tốc độ phần cứng dù có tang lên đi nữa thì tốc độ phần mềm cũng chẳng hề thay đổi gì.

Định luật Brook

Đây là một định luật dựa trên kinh nghiệm thực tế : “Đưa thêm người vào 1 project đang chậm, sẽ chỉ khiến nó càng chậm hơn.”
Hay có thể nói theo một cách khác nữa là “Tập hợp 9 bà bầu lại cũng không thể khiến đứa trẻ ra đời sau 1 tháng.”
Luận thuyết cơ bản của định luật này là:

Định luật Conway

“Organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations.”
“Một công ty thiết kế hệ thống thế nào cũng sẽ làm ra những thiết kế giống y hệt với thiết kế hệ thống của chính công ty họ.”
Nghiên cứu gần đây chỉ ra rằng hệ thống của công ty là nhân tố ảnh hưởng lớn nhất đến vấn đề phát sinh ra bug của sản phẩm.

Nguyên tắc bất ngờ nhỏ nhất (least astonishment)

Trong trường hợp trên cùng 1 interface có 2 yếu tố hành xử mâu thuẫn với nhau, hoặc cách hành xử không rõ ràng thì cần phải chọn cách hành xử nào gây bất ngờ ít nhất cho người sử dụng.
Đây là 1 nguyên tắc về giao diện người dùng.
Một ví dụ đơn giản :
Trên 1 interface có 2 chức năng :
  • Ấn ctrl+Q để thoát chương trình.
  • Nhập macro (lưu 1 tổ hợp phím mang 1 chức năng nào đó để tiện cho việc sử dụng về sau).
Sẽ có trường hợp user muốn dùng Ctrl+Q cho macro của mình, nên hành xử đúng với nguyên tắc bất ngờ nhỏ nhất chính là : trong khi nhập macro thì ctrl+Q được coi như là tổ hợp phím bình thường, không phải là lệnh tắt chương trình. Đây chính là điều gây bất ngờ ít nhất cho người dùng.

Nguyên tắc Boy Scout

Nguyên tắc của các tổ chức Boy scout chính là : lúc đi phải sạch đẹp hơn lúc đến.
Trong lĩnh vực lập trình thì nguyên tắc đó sẽ được hiểu là “Khi bạn checkin 1 module thì lúc đó nó phải đẹp hơn lúc bạn checkout.”

Nguyên tắc YAGNI

Viết tắt của “You ain’t gonna need it” – Cái (chức năng, phần) ấy rồi sẽ không cần thiết.
Đó là một câu khẩu ngữ nhắc nhở người lập trình rằng trong quy trình Extreme Programming (lập trình cực hạn) thì : “Chưa phải lúc cần thiết thì chưa được phép làm.”

Nguyên tắc DRY

Viết tắt của “Don’t repeat yourself” – với ý nghĩa là “Đừng lặp lại những gì giống nhau”.
Khi nguyên tắc này được áp dụng tốt, dù ta có thay đổi 1 phần thì những phần không liên quan cũng sẽ không bị thay đổi theo. Hơn nữa, những phần có liên quan sẽ được thay đổi cùng 1 lượt, giúp ích rất nhiều cho cả khâu estimate và khâu thực hiện.

Nguyên tắc KISS

Viết tắt của “Keep it simple, stupid” – “Cứ đơn giản thôi, đồ ngu!”. Đây là 1 triết lí của Hải quân Mỹ.
Những triết lý tương tự có thể kể đến là :
Phương châm dao cạo Okham (Okham’s razor) – “Không đưa ra nhiều giả thiết nếu không cần thiết. Cái gì cần ít giả thiết để chứng minh sẽ không thể chứng minh được bằng nhiều giả thiết.”
Albert Einstein – “Làm cái gì cũng nên đơn giản nhất có thể, nhưng đơn giản quá thì không được”.
Leonardo da Vinci – “Đơn giản nhất chính là tinh xảo nhất”.
Antoine de Saint- Exupéry – “Hoàn hảo, không phải là không thêm vào được nữa, mà là không thể bớt đi được nữa”.

Nguyên tắc SOLID

Tập hợp những nguyên tắc trong lập trình hướng đối tượng. Các chữ cái đầu hợp lại thành SOLID.
SRP (Single Responsibility Principle) – “Một class chỉ được có 1 nhiệm vụ” hay nói cách khác, “nếu muốn chỉnh sửa class thì chỉ được phép có 1 và chỉ 1 lý do”.
OCP (Open/closed principle) – “Mở class khi cần mở rộng nó, đóng class khi cần chỉnh sửa nó”.
LSP (Liskov substitution principle) – “Subtype phải luôn có thể được thay thế bằng supertype”.
ISP (Interface segregation principle) – “Việc dùng nhiều interface cho các client khác nhau, tốt hơn là việc chỉ dùng 1 interface cho cùng lúc nhiều mục đích” hay nói cách khác “Không được phép hạn chế access vào những method mà client không sử dụng”.
DIP (Dependency inversion principle) – “Module tầng trên không được phụ thuộc vào module tầng dưới. Bất cứ module nào cũng phải phụ thuộc vào cái trừu tượng, không phải vào cái cụ thể”.

Những thói quen xấu kìm hãm sự tiến bộ của lập trình viên

Những thói quen xấu kìm hãm sự tiến bộ của lập trình viên


Gần đây, tôi được phân công hỗ trợ những người lập trình chưa giỏi, dưới hình thức một kèm một (pair programming). Trong khi làm công việc đó, tôi nhận thấy có một vài thói quen xấu khiến họ khó tiến bộ và thói quen tốt nữa mà tôi sẽ liệt kê ra như dưới đây.

Sức mạnh của thói quen

Hàng ngày, tôi vẫn tự hỏi mình năng lực lập trình là do thứ gì quyết định? Có người học lập trình rất nhanh nhưng có người lại học rất chậm. Thông thường, người ta hay gọi cái đó là “cảm giác tốt, cảm giác chưa tốt” và cho qua.
Nhưng tôi thấy rõ ràng có những yếu tố quyết định đến việc học nhanh hay chậm.
Vài năm trước vào một lần nọ, tôi có xem màn hình của đồng nghiệp ngồi bên cạnh và thỉnh thoảng đi quanh phòng làm việc xem màn hình của những người khác nữa. Có một điều làm tôi thực sự ngạc nhiên. Người hay “nộp bài” chậm thì màn hình lại thường có xu hướng hiển thị stack trace (dùng cho đầu ra của web application).
Đồng nghiệp ngồi cạnh tôi thường lập trình theo quy trình dưới đây. Tôi không thống kê chi tiết, nhưng đại loại là vậy.
  • Viết code
  • Lưu code
  • Switch màn hình sang browser
  • Reload
  • Màn hình lỗi hiện ra
  • Switch sang màn hình code luôn
Như thế này thì tôi nghĩ năng suất làm việc sẽ rất tồi. Phải nói thêm là cậu ta đang viết một phần thuộc model (và tất nhiên phần đó có ở bên controller nữa). Ngay lập tức, tôi chỉ cho cậu ấy cách check syntax và cách chạy thử từng module. Dựa vào đó, tôi chỉ thêm cho cậu ấy cách viết những test code nhỏ cho phần logic nữa. Nhưng hình như cậu ấy vốn đã biết cả rồi. Tuy nhiên, vì nghĩ là phiền phức nên cậu ấy đã bỏ qua. Tôi hỏi tại sao lại phiền thì cậu ấy có hơi lúng túng, giải thích khá nhiều nhưng đại ý là “Đằng nào cũng phải hiển thị, nên xem nó hiển thị thế nào là nhanh nhất”. Đây là vấn đề về thói quen. Ngày đó công ty tôi chưa có quy trình CI (continous integration) nên hầu như không ai có thói quen viết test cho code cả.
Về sau, quy trình CI được áp dụng, việc viết test cho code trở thành bắt buộc. Tuy nhiên khi đó thì sau khi hiển thị ngon hết rồi cậu ta mới viết, với một thái độ không lấy gì làm vui vẻ cho lắm. Quy trình phía trên của cậu ấy, do chạy code sau khi đã ghép nên màn hình sẽ hiện một đống lỗi rất phức tạp làm cho công việc kéo dài ra. Cậu ta dường như không quan tâm đến chuyện đó mà có khi cũng chẳng đọc lỗi nữa. Cậu ấy không quen test từng phần một, mà sau khi ghép code sẽ khó test hơn rất nhiều. Quy trình vốn sinh ra để tăng năng suất, bây giờ do thói quen của người làm việc, thành ra lại làm giảm năng suất.

Thói quen xấu

Gần đây, tôi có pair programming với vài kĩ sư trẻ. Một ngày tôi làm với họ vài tiếng, chiếm phần lớn thời gian ở công ty của tôi. Tôi sẽ giới thiệu vài thói quen xấu của họ mà trong khi làm việc tôi đã phát hiện và nhắc nhở.

Ít đọc code

Tùy từng project mà thời gian đọc code khác nhau, nhưng nhìn chung thời gian đọc code luôn chiếm tỉ lệ lớn. Cách phân bố thời gian thường thấy là 80% đọc, 20% viết. Đọc code là bắt buộc để có thể hiểu được những phần liên quan, và hiểu framework. Đối với những kĩ sư mà công việc hay bị trục trặc, không tiến triển, tôi thấy tỉ lệ thời gian họ dành cho việc đọc code là rất thấp. Một ví dụ là có một cậu định sử dụng chức năng có trong framework thì bị lỗi. Tôi nói với cậu ấy là ở framework đang hiển thị lỗi sai đầu vào. Tuy nhiên cậu ấy sau đó không hề xem chỗ tôi bảo trên framework. Vậy thì cậu ấy làm gì?
Nhìn chăm chú vào code của mình, ngẩn ngơ tìm chỗ sai. Nghiền ngẫm một đoạn code trên mạng để xem có nên copy paste không. Nghĩa là cứ khi nào code không chạy thì cậu ấy đều ngồi xem code mình viết có gì sai.

Cách sửa

Tôi chỉ cho cậu ấy cách tìm đoạn bị sai tương ứng trên framework. Đồng thời, tôi bảo cậu ấy đọc xem đoạn ấy xử lí cụ thể như thế nào và kết luận tại sao code không chạy.

Vấn đề tâm lí

Tôi hỏi tại sao cậu ấy không đọc code của framework thì cậu ấy trả lời rằng “Nhìn phức tạp lắm, với lại em muốn làm xong sớm”. Tôi cũng công nhận là nội dung bên trong framework phức tạp thật, và đúng là rất khó để nắm được tổng thể. Tuy nhiên bằng cách nghiên cứu nó, kiến thức về ngôn ngữ và khả năng đọc hiểu thư viện sẽ tăng lên, trình độ bản thân sẽ tăng lên. Tôi đã cho cậu ấy trải nghiệm việc phá bỏ rào cản tâm lí đó, ngồi nghiên cứu code sẽ khiến vấn đề được giải quyết nhanh như thế nào.
Vì những lẽ ở trên, tôi nghĩ là người hướng dẫn cũng không nên nói những câu đại loại như “Phần này không hiểu cũng được”, “Đừng đọc nhiều làm gì, cứ cho chạy đi đã” - điều đó cũng rất quan trọng. Tôi luôn nghĩ : giới hạn trưởng thành của bạn cao đến mức nào, phụ thuộc vào việc bạn hiểu code sâu đến mức nào.

Không test riêng những đoạn xử lí phức tạp

Vệc chia nhỏ các hàm rất quan trọng. Tại sao lại phải chia? “Vì như thế thì sẽ nhàn hơn”. Tuy nhiên đối với người chưa thuần thục thì lại cảm thấy như thế là “khổ hơn”.
Ví dụ:
Ruby
function process(list){

    for(var i=0,l=list.length;i<l;i++){
        ...
        // viết cái gì cần xử lí
    }

    ...
    // xử lí thêm gì nữa thì viết vào đây`

}
Hàm có cấu trúc như thế này nghĩa là muốn thực hiện xử lí riêng từng phần một. Người chưa thuần thục thường có xu hướng cứ thế viết những gì muốn xử lí vào những chỗ comment ở trên.
Nhưng đúng ra nó phải là như thế này :
Ruby
function process(list){
    var next = []:
    for(var i=0,l=list.length;i<l;i++){
        ...
        var elem = doSomethingForElement(list[i]);

        if ( elem ) {
            next.push(elem):
        }
    }

    ...

    if( next.length == 0 ){
        return doSomethingWhenNoResponse(args);
    }

    ...

}

function doSomethingForElement(){
    #viết những gì cần xử lí
}

function doSomethingWhenNoResponse(){
    #viết những gì cần xử lí
}
Những phần muốn xử lí viết tách ra ngoài, độc lập (gọi là sprout method). Làm như thế sẽ tránh cho hàm gốc bị phức tạp hóa, và giúp ta test được từng xử lý một.

Cách sửa

Tôi cho họ làm quen với quy trình là trước khi động tay vào hàm gốc thì hãy tách những gì mình cần xử lí ra thành những hàm rời, sau đó viết và test những cái rời trước. Sau đó họ đã thấy kết quả là việc giải quyết lỗi phát sinh trở nên nhanh như thế nào. Đồng thời, tôi giúp họ ý thức đầu ra đầu vào là gì, phần mình làm ảnh hưởng các phần khác như thế nào.

Vấn đề tâm lí

Nguyên nhân của chuyện cảm thấy việc chia nhiều hàm là khổ chính là từ suy nghĩ “muốn xong sớm” mà ra. Họ nghĩ “Sau này có lỗi thì chỉ cần xem lỗi ở đâu rồi sửa là xong” nên họ thấy chia nhiều hàm rất là “phức tạp hóa vấn đề”, chỉ là chuyện “nếu thừa thời gian thì làm”. Tuy nhiên, nếu gộp hết tất cả thành 1 hàm rồi chạy, thì việc hiểu code sẽ rất khó và cái vòng luẩn quẩn “chạy và lỗi” sẽ kéo dài, lỗi lại còn rất nặng. Như thế mới chính là đang làm mất thời gian. Cũng như trong Hình học để giải bài toán ta hay phải kẻ đường phụ. Việc học cách kẻ đường đó như thế nào là một điều rất quan trọng.

Không kiểm tra quy trình làm việc của bản thân

Như phần đầu tôi đã nói, thói quen chính là sức mạnh. Chúng ta cần phải có một quy trình làm việc nhanh nhất có thể, hướng đến mục tiêu là tự động hóa.
Từ hôm pair programming, tôi mới nhận ra một cậu hay ngồi nhìn code chằm chằm sau khi viết. Tôi hỏi là đang làm gì thế thì cậu ấy bảo “Em đang kiểm tra”. Cậu ấy đúng là đang kiểm tra từng dòng code một, xem mình có viết sai gì không. Tôi bảo cậu ấy trước tiên hãy check syntax đi thì cậu ấy hỏi “Check syntax nghĩa là sao ạ?”. Sau khi tôi chỉ cậu ấy cách làm thì cậu ấy sau đó cứ liên tục hỏi tôi “Câu này đúng chưa anh?”, “Thế này được chưa?”. Tôi trả lời là trước hết cứ tự mình kiểm tra đi đã, cậu ấy không hiểu ý tôi là gì.
Tôi đã nhận ra rằng ngoài quy trình check xem code của mình sau khi build và cho chạy thật đã ngon chưa, họ không có thêm một quy trình nào khi làm việc cả. Unit test vốn là thứ được sinh ra để xem từng phần có hoạt động chính xác không. Nếu trong khi làm không chuẩn bị trước, không phải là người có thói quen vừa làm vừa test (test first), thì sau này làm unit test sẽ rất mệt.

Cách sửa

Phần code dùng để check syntax hãy để riêng ra editor và dùng thường xuyên. Nếu cần thiết, cứ khi save code là tự động cho chạy luôn để test. Vì cậu ấy dùng editor là vim nên cần cài plugin như quickrun hay syntastic.
Các class và các hàm cũng vậy, ở đâu cũng được, nhưng cần phải tạo môi trường để kiểm tra từng cái một. Nếu kiểm tra thấy ngon rồi, thì hãy lưu lại vào một file test. Đó là quy trình mà tôi muốn cậu ấy thực hiện. Trước khi hỏi “Thế này được chưa” thì hãy làm tất cả những việc trên đã. Khi đã quen rồi, nên tạo một môi trường CI dựa trên cách dùng debug hoặc fswatch. Mỗi khi save code thì cho chạy luôn cái CI đó để test là tốt nhất.

Vấn đề tâm lí

Vấn đề về môi trường như bên trên có vẻ như liên quan đến kiến thức chứ không liên quan đến tâm lí. Tuy nhiên sau khi phân tích, tôi thấy nó liên quan đến nhận thức về 2 khái niệm thường gặp khi lập trình là “code chuẩn” và “code lỗi mà không biết vì sao”.
Một thực tế là, không phải chỉ có duy nhất một “code chuẩn”.
Tuy nhiên, người hay copy paste thường có xu hướng nghĩ rằng : copy paste mà cũng không chạy được thì chắc là do mình thao tác sai chỗ nào đó, copy paste bị thiếu chỗ nào đó và thường có thói quen ngồi tìm kiếm những cái đó. Vì lí do đó, code của họ sau khi viết xong chẳng khác nào mật mã ngoài hành tinh, và họ sẽ phải tìm lỗi sai trong đống mật mã đó. Phần mà họ tự viết ra cũng dựa trên những đoạn copy paste, mà sau này rồi cũng sẽ trở thành thứ mà họ không thể tự lí giải nổi. Tâm lí của họ là luôn nghĩ việc đọc hiểu và kiểm tra từng dòng một, kém năng suất hơn việc copy paste cả một đoạn rất nhiều.

Không đọc error message, không đọc log

Error message của ngôn ngữ lập trình, hay error message của thư viện đều có nhiệm vụ là chỉ ra chỗ sai bằng văn bản con người có thể hiểu được, viết bởi con người. Tuy nhiên, những lập trình viên tiến bộ chậm thường không đọc những cái đó. Họ chỉ ý thức được là có lỗi xảy ra. Nếu là code trên IDE thì có thể kích chuột để jump ngay đến câu lệnh lỗi. Nhưng nếu làm trên vim hoặc Web browser thì việc đọc hiểu log message, và jump đến câu lệnh lỗi là nhiệm vụ của người lập trình. Không đọc, cũng không jump đến câu lệnh lỗi nên màn hình error thường bị switch đi trong tích tắc. Trong khi pair programming với vài người, họ switch màn hình nhanh đến nỗi tôi còn tưởng họ đang thử độ phản ứng của mắt với vật thể chuyển động.
Kết quả là họ ngồi nhìn chằm chằm vào code họ vừa viết, tìm xem có lỗi chính tả, lỗi font nào không bằng cách ngó đi ngó lại method name. Vấn đề là error message vừa nãy đâu có nói là method name có lỗi, hoặc không tồn tại. Một khi không đọc error message thì phạm vi có thể phát sinh lỗi là vô hạn. Tuy nhiên, họ chỉ luôn nghĩ được là mình “viết sai một cái gì đó”.

Cách sửa

Tất nhiên là đọc error message và tìm hiểu ý nghĩa của từng message một. Thêm vào đó, tôi giúp họ lí giải mối liên hệ giữa error message và môi trường. Đồng thời, hướng dẫn họ tạo ra những đoạn code nhỏ để tái hiện các lỗi đó (snippet) có thể dùng cho sau này và dự trù các case tương tự có thể xảy ra.

Vấn đề tâm lí

Có thanh niên nói “Em sợ tiếng Anh lắm, nhìn cứ như mật mã”. Có điều, ngữ pháp của các error message chỉ dừng ở mức học sinh cấp Hai, mà tôi biết là cậu ta thừa sức hiểu. Cũng phải công nhận một thực tế là muốn hiểu những lỗi liên quan đến ngôn ngữ lập trình và framework thì phải hiểu cấu trúc và từ ngữ chuyên ngành của chúng. Điều này khó. Nhưng như vậy không có nghĩa là ngôn ngữ hoặc framework đó “không thân thiện” mà vì bản thân error message không phải sinh ra chỉ để hiển thị những lỗi liên quan đến code người lập trình viết.
Vì vậy ta cần theo sát cả framework, cả ngôn ngữ lập trình, và cả code. Có như vậy ta mới có thể móc nối error message và vấn đề cần giải quyết với nhau. Để có thể tự mình làm như vậy, hàng ngày cần tự tạo thói quen tìm hiểu những thứ đó cho mình. Nếu không cho dù đến bao giờ chăng nữa, error message cũng vẫn mãi chỉ là những “mật mã” mà thôi.

Không biết cách đào sâu vấn đề

Có lỗi xảy ra, nghĩa là chúng ta có thể tìm ra manh mối để giải quyết vấn đề bằng cách xem xét phần code bị báo lỗi. Ở đó có lỗi, nghĩa là ít nhất thì code đã chạy được cho đến đó. Hơn thế nữa, nguyên nhân lỗi phát sinh rất có thể là do ảnh hưởng của những gì mà chúng ta đã nhập vào. Chẳng hạn, bằng cách dùng printf để debug, chúng ta có thể biết nhập cái gì vào module, biến đổi nó ra sao thì sẽ sinh ra lỗi. Thông qua việc đó, chúng ta sẽ hiểu khái quát vấn đề, sau đó tuần tự thử các bước chạy của chương trình là có thể chỉ ra được cụ thể phần nào bị lỗi.
Tuy nhiên, người không biết cách đào sâu vấn đề thường cho chương trình chạy với tâm lí là sẽ chạy ngon và check code với tâm lí “đáng ra nó phải chạy ngon”. Họ thường không quan tâm đến thứ tự các bước chạy của chương trình, cách làm việc của họ chẳng khác nào lần mò trong đám mây. Trong một vài trường hợp, họ sẽ mãi “ngẩn ngơ” vì không hiểu sai từ đâu. Họ không có trong tay một chiến thuật để tìm ra chỗ sai nên sẽ nhanh chóng rơi vào trạng thái người ta vẫn gọi là “quay cuồng”.

Cách sửa

Sau khi xảy ra lỗi, trước khi họ làm một động tác gì tôi đều yêu cầu họ trả lời câu hỏi này trước “Bây giờ chúng ta cần làm gì?”. Cụ thể, tôi muốn họ nêu ra phương pháp tìm ra chỗ sai. Tôi giúp họ xây dựng phương pháp đó bằng cách hỏi những câu như “Code chạy ngon đến đoạn nào?”. Sau khi tìm ra một manh mối gì đó, tôi lại hỏi “Thông tin này có ý nghĩa gì?”, “Có cần thay đổi phương pháp không?”. Tôi muốn họ ý thức được là mình cần đào sâu có mục tiêu đàng hoàng, chứ không phải là lần mò trong đám mây.

Vấn đề tâm lí

Đối với một chương trình, việc xảy ra lỗi là một minh chứng cho việc “đã gần hoàn thiện”. Tại sao? Vì nó thường chỉ cho ta sáng tỏ một điều mà trước đây ta không quan tâm, chỉ cho ta biết giả thiết mà ta đã tạo ra là sai, và chỉ cho ta hành động tiếp theo mà ta phải làm là sửa nó. Ta đã có định hướng. Tuy nhiên, đối với những progammer không giỏi đào sâu vấn đề thì thường có xu hướng bị “ngây người” vì họ luôn nghĩ rằng “Đáng ra phải chạy ngon rồi chứ nhỉ?”. Và sau đó họ lại nghĩ “Toi rồi, sai hết rồi”. Có thể nói rằng họ không bao giờ test những cái mà chắc sẽ thất bại, trong khi giá trị cao nhất của việc test là sau khi thất bại, nó sẽ cho ta một thông tin hữu ích nào đó.
Tôi bảo họ chạy thử thì họ thường nói “Lỗi là cái chắc” và không làm. Còn khi miễn cưỡng làm rồi chương trình không chạy thì họ bảo “Đấy, thấy chưa?”. Thực tế là lỗi ở môi trường chạy thật thì không được phép, nhưng ở môi trường test thì sẽ chẳng có ai phàn nàn gì cả, thậm chí còn có ích. Tôi nghĩ họ cần được tự mình trải nghiệm và lí giải những điều đó.

Thói quen tốt

Dựa vào những thói quen xấu đã nói ở trên, chúng ta có thể biết được đâu là thói quen tốt.
  • Đầu tư thời gian để đọc code và hiểu code.
  • Luôn có xu hướng dùng kiến thức để đơn giản hóa vấn đề trước mắt
  • Không sợ lỗi, luôn dùng test code để tìm kiếm thông tin, manh mối
  • Luôn hành động với mục đích rõ ràng để từng bước một giải quyết vấn đề
Ngoài ra, còn vài thói quen mà tôi nghĩ là tốt như :
  • Cải tiến công cụ và tự động các hóa quy trình
  • Boy scout policy
  • Học vài ngôn ngữ
  • Học kiến thức một cách tổng thể

Cải tiến công cụ và tự động hóa các quy trình

Thói quen tốt thường được hỗ trợ bởi công cụ tốt. Chẳng hạn mỗi khi học ngôn ngữ mới, tôi đều tìm kiếm code formatter của ngôn ngữ đó. Ngoài ra, tôi có coding style của mình - không muốn ấn quá nhiều phím, nên tôi chọn IDE có chức năng tự động nhập space cho tôi.

Boy scout policy

Có một tổ chức gọi là boy scout có phương châm là : nhặt hết rác trên các đoạn đường mình đi qua. Cũng như vậy, người lập trình cần có phương châm sửa hết lỗi của những code liên quan đến phần mình làm. Dĩ nhiên không đọc cẩn thận thì sẽ không sửa được, nhưng dù không sửa thì đọc code thôi cũng là có ích rồi. Làm như vậy thì tự nhiên sẽ ngày càng hiểu sâu về code hơn, và code tổng thể sẽ đẹp hơn.

Học vài ngôn ngữ

Nhiều khi vấn đề ở ngôn ngữ này ta có thể lí giải được trong khi học ngôn ngữ khác. Và nhiều khi, một khái niệm nghe có vẻ lạ, thực ra chỉ là đem từ ngôn ngữ khác vào. Thế nên, việc học nhiều ngôn ngữ sẽ giúp ta lập trình mau thuần thục hơn.

Học kiến thức một cách tổng thể

Kiến thức về background, về lịch sử ngôn ngữ, và vài ba bài tập ta đọc ở đâu đó sẽ khiến cho chất lượng code của ta tăng lên. Nếu mỗi ngày ta không gặm nhấm một ít kiến thức, không có cách hiểu về cú pháp, về sample của riêng ta thì kiến thức sẽ không còn là kiến thức mà chỉ dừng ở mức mẹo vặt vì ta không biết ứng dụng chúng sang những trường hợp khác. Cứ thế, ta sẽ chỉ mãi mãi chạy theo những mẹo vặt để giải quyết vấn đề mà thôi.

Lời kết

Năng lực tạo ra bởi tập hợp các thói quen nên việc cải thiện các thói quen sẽ khiến cho năng lực của chúng ta tăng lên. Đó là suy nghĩ của tôi. Tiếp theo là do những rào cản tâm lí nên bản thân việc cải thiện các thói quen cũng thường không mấy dễ dàng. Cải thiện xong rồi, cũng không phải ngay lập tức đạt đến trình độ siêu nhân ngay được.
Nhưng đừng bao giờ nghĩ rằng mình vô dụng. Điều ảnh hưởng nhất đến kết quả cuối cùng của bạn là việc bạn có nghĩ được rằng : con đường học những điều mới là con đường hạnh phúc, hay không.
Theo Viblo/Phan Hoang Minh
Bài viết được đăng trên blog Fsd14, các bạn có thể copy về blog của mình hoặc share bất kỳ đâu nhưng vui lòng ghi rõ nguồn về blog fsd14 như một sự tôn trọng công sức biên soạn và dịch bài của tác giả. 

Xin cảm ơn các bạn!

Bài mới

Bài đăng nổi bật